import http from '@/utils/http.js';
import COS from 'cos-js-sdk-v5';
import SparkMD5 from 'spark-md5';
import { getFileType } from '@/utils';
import { addFile } from '@/apis/file';
import { useFileStore } from '@/stores';
const fileStore = useFileStore();
const Bucket = 'okpan-1323065891';
const Region = 'ap-nanjing';

export async function uploadFile(
  authorization,
  requestId,
  file,
  folderId = 0,
  isAvatar
) {
  fileStore.clearSchedule();
  return new Promise(async (resolve, reject) => {
    try {
      // const arrayBuffer = await file.arrayBuffer();
      // const md5 = SparkMD5.ArrayBuffer.hash(arrayBuffer)
      // const MIME = file.type;
      const size = file.size;
      const { type, extension } = getFileType(file.name);

      // const { authorization, requestId } = await getTmpSecret();
      const cos = new COS({
        getAuthorization: function (options, callback) {
          callback(authorization);
        },
        Protocol: 'https:'
      });
      const res = await cos.uploadFile({
        Bucket,
        Region,
        Key: 'test/' + requestId + '_' + file.name,
        Body: file,
        SliceSize: 1024 * 1024 * 10,
        onProgress: function (progressData) {
          let progress = progressData.percent * 100;
          fileStore.setSchedule(progress.toFixed(2));
        }
      });

      // const url = 'https://' + res.Location
      const url = 'test/' + requestId + '_' + file.name;
      const data = {
        name: file.name,
        size,
        icon: url,
        ext: extension,
        url,
        folder_id: folderId,
        type: fileStore.Type
      };
      if (isAvatar) {
        resolve({ data });
        return;
      }
      const { status, message } = await addFile(data);
      if (status !== 0) {
        throw new Error(message);
      }
      resolve({ status, message, data });
    } catch (e) {
      reject({ errMsg: e, name: file.name });
    }
  });
}

function restrictConcurrency(asyncFn, size) {
  const workingQueue = new Set();
  const waitingQueue = [];
  const run = function (...args) {
    return new Promise((resolve, reject) => {
      const startTask = () => {
        const promise = asyncFn(...args)
          .then(resolve)
          .catch(reject);
        workingQueue.add(promise);
        promise.finally(() => {
          workingQueue.delete(promise);
          if (waitingQueue.length > 0) {
            waitingQueue.shift()();
          }
        });
      };
      if (workingQueue.size < size) {
        startTask();
      } else {
        waitingQueue.push(startTask);
      }
    });
  };
  return run;
}

export const upload = restrictConcurrency(uploadFile, 8);
